#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <signal.h> 
#include <stdlib.h>       
#include <string.h>
#include <pthread.h>
//#include <sys/sem.h>
#include <errno.h>
#include <sys/ipc.h>
//#include <sys/msg.h>
#include <sys/timeb.h>
#include <sys/socket.h>
//#include <sys/socketvar.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <semaphore.h>
#include <string.h>
#include <termios.h>
#include <linux/input.h>
#include <semaphore.h>
#include <linux/shm.h>
#include <asm/unistd.h>
#include <sys/poll.h>

/*
#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>

struct CameraCapture
{
		char rtspUrl[1024];
		void(*pCallBack)(unsigned char *,int size);
};

static void* ConnectThread(void* arg);
static int interrupt_cb(void *ctx);

void InitFFmpeg()
{
		av_register_all();
		avcodec_register_all();
		avformat_network_init();
}

int startCamera(const char *rtspUrl,void(*pCallBack)(unsigned char *,int size)) 
{ 
		pthread_t ptID;
		struct CameraCapture *cc = (struct CameraCapture*)malloc(sizeof(struct CameraCapture));
					
		strcpy(cc->rtspUrl,rtspUrl);
		cc->pCallBack = pCallBack;		
						
		if( pthread_create(&ptID, NULL, ConnectThread, (void *)cc) != 0 )
		{
				printf("thread failure {%s(%d)}\n",__FILE__,__LINE__);		
				return;
		}				
}


int ConnectCamera(void* arg)
{	
		AVFormatContext *i_fmt_ctx = NULL;  
		AVStream *i_video_stream   = NULL; 
		int video_stream_index     = -1;
		AVDictionary* options = NULL; 
		
		unsigned i;	
		int  err_code;
		char buf[800];	
    
    struct CameraCapture *cc = (struct CameraCapture *)arg;
    
  	i_fmt_ctx = avformat_alloc_context();
    i_fmt_ctx->interrupt_callback.callback = interrupt_cb;
    i_fmt_ctx->interrupt_callback.opaque = i_fmt_ctx;
    
    //av_dict_set(&options, "rtsp_transport" , "tcp" , 0); 
    av_dict_set(&options, "timeout", "6000", 0); 
    
    //char rtspUrl[] = "rtsp://admin:admin@192.168.100.213:554/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif"; 

    if ( err_code = avformat_open_input(&i_fmt_ctx, cc->rtspUrl, NULL, NULL ) ) 
    { 
 				av_strerror(err_code, buf, 800);
				printf("Couldn't open file: %d(%s)\n", err_code, buf); 
    		av_free(i_fmt_ctx);  	
        return -1; 
    }

    if (avformat_find_stream_info(i_fmt_ctx, NULL)<0) 
    { 
		    avformat_close_input(&i_fmt_ctx);
		    av_free(i_fmt_ctx);    	
        return -2; 
    }

    // find first video stream 
    for (i=0; i<i_fmt_ctx->nb_streams; i++) 
    { 
        if (i_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) 
        { 
        		video_stream_index = i;
            i_video_stream = i_fmt_ctx->streams[i]; 
            break; 
        } 
    } 

    if (i_video_stream == NULL) 
    { 
		    avformat_close_input(&i_fmt_ctx);
		    av_free(i_fmt_ctx);     	
        return -3; 
    }

    while ( !IsExitC() )  
    { 
        AVPacket i_pkt; 
        av_init_packet(&i_pkt); 
        i_pkt.size = 0; 
        i_pkt.data = NULL; 
        ;
        if ( av_read_frame( i_fmt_ctx, &i_pkt ) < 0 ) 
        {
            break; 
				}
							
				if( video_stream_index != i_pkt.stream_index )
				{
						av_free_packet(&i_pkt); 
						continue;
				}
				
				cc->pCallBack(i_pkt.data,i_pkt.size);
				
        av_free_packet(&i_pkt); 
    } 

    avformat_close_input(&i_fmt_ctx);
    av_free(i_fmt_ctx);

    return 0; 
}

static void* ConnectThread(void* arg)
{
	  while ( !IsExitC() )  
	  { 	
				ConnectCamera(arg);
		}
		return 0;	
}

static int interrupt_cb(void *ctx)
{
		return  0;
}
*/
